package com.example.libary.interceptor;

import com.example.libary.common.Result;
import com.example.libary.common.ResultCode;
import com.example.libary.entity.User;
import com.example.libary.service.UserService;
import com.example.libary.util.JwtUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.PrintWriter;
import java.util.Collections;
import java.util.List;

/**
 * JWT拦截器
 */
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private UserService userService;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = request.getRequestURI();
        log.debug("JWT拦截器处理请求: {}", requestURI);
        
        // 获取请求头中的token
        String token = request.getHeader("Authorization");
        log.debug("获取到的Authorization头: {}", token);
        
        // 打印所有请求头，帮助诊断问题
        log.debug("所有请求头:");
        request.getHeaderNames().asIterator().forEachRemaining(name -> 
            log.debug("Header: {} = {}", name, request.getHeader(name))
        );
        
        // 如果没有token，返回未授权错误
        if (!StringUtils.hasText(token)) {
            log.debug("Authorization头为空，返回未授权错误");
            handleUnauthorized(response, "请先登录后再访问");
            return false;
        }
        
        // 如果token以Bearer开头，去掉Bearer
        if (token.startsWith("Bearer ")) {
            token = token.substring(7);
            log.debug("去掉Bearer前缀后的token: {}", token);
        } else {
            log.debug("Token格式不正确，应以'Bearer '开头，当前token: {}", token);
            handleUnauthorized(response, "Token格式不正确，应以'Bearer '开头");
            return false;
        }
        
        // 验证token
        try {
            boolean valid = jwtUtil.validateToken(token);
            log.debug("Token验证结果: {}", valid);
            if (valid) {
                String username = jwtUtil.getUsernameFromToken(token);
                log.debug("Token中的用户名: {}", username);
                
                // 获取用户信息
                User user = userService.getByUsername(username);
                if (user != null) {
                    // 设置Spring Security认证上下文
                    setAuthenticationContext(user);
                    
                    // 将用户名添加到请求属性中，方便后续使用
                    request.setAttribute("username", username);
                    request.setAttribute("user", user);
                    return true;
                } else {
                    log.debug("用户不存在: {}", username);
                    handleUnauthorized(response, "用户不存在");
                    return false;
                }
            } else {
                log.debug("Token无效");
                handleUnauthorized(response, "登录已过期或无效，请重新登录");
                return false;
            }
        } catch (Exception e) {
            log.error("Token验证异常", e);
            handleUnauthorized(response, "登录验证失败: " + e.getMessage());
            return false;
        }
    }
    
    /**
     * 设置Spring Security认证上下文
     */
    private void setAuthenticationContext(User user) {
        // 根据用户角色设置权限
        String role = "ROLE_USER"; // 默认为普通用户
        if ("0".equals(user.getRole())) {
            role = "ROLE_ADMIN"; // 管理员
        }
        
        List<SimpleGrantedAuthority> authorities = Collections.singletonList(
            new SimpleGrantedAuthority(role)
        );
        
        UsernamePasswordAuthenticationToken authentication = 
            new UsernamePasswordAuthenticationToken(user.getUsername(), null, authorities);
        
        SecurityContextHolder.getContext().setAuthentication(authentication);
        log.debug("设置用户 {} 的认证上下文，角色: {}", user.getUsername(), role);
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清理认证上下文
        SecurityContextHolder.clearContext();
        log.debug("清理认证上下文");
    }
    
    /**
     * 处理未授权错误
     */
    private void handleUnauthorized(HttpServletResponse response, String message) throws Exception {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType(MediaType.APPLICATION_JSON_VALUE);
        response.setCharacterEncoding("UTF-8");
        
        Result<Void> result = Result.error(ResultCode.UNAUTHORIZED.getCode(), message);
        log.debug("返回未授权错误: {}", message);
        
        PrintWriter writer = response.getWriter();
        writer.write(new ObjectMapper().writeValueAsString(result));
        writer.flush();
    }
} 